package signHelper.mvc.controller;

import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import signHelper.mvc.filter.WebContext;
import signHelper.modle.User;
import signHelper.permission.shiro.ShiroSessionUtils;
import signHelper.service.UserService;

@Api("用户登录")
@Controller
public class LoginController {

	private final Logger logger = LogManager.getLogger(getClass());
	private @Autowired UserService service;
	
	/**
	 * 登陆页的映射
	 * 
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/")
	public String login(Model model) throws Exception {
		return "/index.html";
	}


	/**
	 * 密码会在校验是进行一次md5，详见 @see ShiroAccountRealm
	 * @param account
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@ApiOperation(value = "登录")
	@ResponseBody
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public Object loginPost(@RequestBody  User account) throws Exception {
		// type 类型用来标注会员类型,0表示普通会员
		Map<String, Object> map = new HashMap<String, Object>();
		
		UsernamePasswordToken token = new UsernamePasswordToken(account.getNumber(), (new Md5Hash(account.getPassword()).toString()));

		HttpServletRequest request = WebContext.currentRequest();
		String rememberme = request.getParameter("rememberme");
		if (StringUtils.isNotBlank(rememberme)) {
			token.setRememberMe(true);
		} else {
			token.setRememberMe(false);
		}

		try {
			Subject subject = SecurityUtils.getSubject();
			subject.login(token);
			if (subject.isAuthenticated()) {
				map.put("status", 0);
				map.put("msg", "登陆成功");
				User user=new User();
				user.setNumber(token.getUsername());
				user=service.query(user, 0, 1).get(0);
				user.setPassword(null);
				map.put("user", user);
				return map;
			}
		} catch (UnknownAccountException uae) {
			map.put("msg", "账号不存在!");
		} catch (IncorrectCredentialsException ice) {
			// 密码不正确
			int num = (Integer) ShiroSessionUtils.getAttribute("loginNum");
			token.clear();
			map.put("msg", "用户名或密码错误,你还可以输入" + (5 - num) + "次");
		} catch (ExcessiveAttemptsException eae) {
			// 输入用户名或密码错误次数过多
			ShiroSessionUtils.setAsLogout();
			token.clear();
			map.put("msg", "输入用户名密码或次数过多,账户已被锁定,半小时后解锁");
		} catch (LockedAccountException lae) {
			map.put("msg", "账号被锁定!");
		} catch (Exception e) {
			logger.error("登录失败", e);
			map.put("msg", "未知错误,请联系管理员.");
		}
		return map;
	}

	/**
	 * 退出
	 * 
	 * @param request
	 */
	@RequestMapping(value = "/logout")
	public String logout(HttpServletRequest request) {
		Subject subject = SecurityUtils.getSubject();
		if (subject != null) {
			subject.logout();
		}
		return "redirect:/";
	}

}